﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <stdlib.h>

//int main(void)
//{
//	int a = 10000;
//	FILE* ptr = fopen("text.txt", "wb");
//	fwrite(&a, 4, 1, ptr);
//	fclose(ptr);
//	ptr = NULL;
//	return 0;
//}
//int main(void)
//{
//	//不在本地文件夹中的文件要加路径，并且\\来防止转义；
//	FILE* ptr = fopen("data.txt", "w");//w为写入，文件若存在先清空在写入，文件若不存在，将会创建一个文件
//	//绝对路径与相对路径
//	//.表示当前路径
//	//..表示上一级路径
//	if (ptr == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	fclose(ptr);
//	ptr = NULL;
//	return 0;
//}
//int main(void)
//{
//	FILE* str = fopen("test.txt", "w");
//	if (str == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	for (char i = 'a'; i <= 'z'; i++)
//	{
//		fputc(i, str);
//	}
//	fclose(str);
//	str = NULL;
//
//	return 0;
//}
//int main(void)
//{
//	FILE* str = fopen("test.txt", "r");
//	if (str == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//	/*for (char i = 'a'; i <= 'z'; i++)
//	{
//		int ASIIC = 0;
//		ASIIC = fgetc(str);
//		printf("%d", ASIIC);
//	}*/
//	int ch = 0;
//	while ((ch = fgetc(str)) != EOF)//要加括号
//	{
//		printf("%c ", ch);
//	}
//	fclose(str);
//	str = NULL;
//
//	return 0;
//}
//看清楚函数的适用类型：所有输入流，标准输入流，文件输入流
//int main(void)
//{
//	int ch = fgetc(stdin);
//	fputc(ch, stdout);
//
//	return 0;
//}
// //文本行输入函数
//fgets();碰到换行会停下来，加上个\0
//int main(void)
//{
//	char arr[20];
//	fgets(arr, 20, stdin);
//	fputs(arr, stdout);
//
//	return 0;
//}
//fread ⼆进制输⼊ ⽂件输⼊流
//fwrite ⼆进制输出 ⽂件输出流
//int main(void)
//{
//	FILE* fp = fopen("test.txt", "r");
//	if (fp == NULL)
//	{
//		perror("fopen");
//		return 1;
//	}
//
//	int ch = 0;
//	ch=fgetc(fp);
//	printf("%c\n", ch);
//
//	ch = fgetc(fp);
//	printf("%c\n", ch);
//
//	fseek(fp, 2, SEEK_CUR);
//
//	ch = fgetc(fp);//读完一次指针往后偏移
//	printf("%c\n", ch);
//
//	printf("%d\n", ftell(fp));//返回⽂件指针相对于起始位置的偏移量
//
//	rewind(fp);//让⽂件指针的位置回到⽂件的起始
//	ch = fgetc(fp);//读完一次指针往后偏移
//	printf("%c\n", ch);
//
//	fclose(fp);
//	fp = NULL;
//
//	return 0;
//}
//int main()
//{
//	FILE* pFile;
//	pFile = fopen("example.txt", "wb");
//	fputs("This is an apple.", pFile);
//	fseek(pFile, 9, SEEK_SET);
//	fputs(" sam", pFile);
//	fclose(pFile);
//	return 0;
//}
/*
	被错误使⽤的 feof
	牢记：在⽂件读取过程中，不能⽤feof函数的返回值直接来判断⽂件的是否结束。
	feof 的作⽤是：当⽂件读取结束的时候，判断是读取结束的原因是否是：遇到⽂件尾结束
	1. ⽂本⽂件读取是否结束，判断返回值是否为 EOF （ fgetc ），或者 NULL （ fgets ）
	例如：
	• fgetc 判断是否为 EOF .
	• fgets 判断返回值是否为 NULL .
	2. ⼆进制⽂件的读取结束判断，判断返回值是否⼩于实际要读的个数。
	例如：
	• fread判断返回值是否⼩于实际要读的个数。
*/
//int main(void)
//{
//	int c; // 注意：int，⾮char，要求处理EOF
//	FILE* fp = fopen("test.txt", "r");
//	if (!fp) {
//		perror("File opening failed");
//		return EXIT_FAILURE;
//	}
//	//fgetc 当读取失败的时候或者遇到⽂件结束的时候，都会返回EOF
//	while ((c = fgetc(fp)) != EOF) // 标准C I/O读取⽂件循环
//	{
//		putchar(c);
//	}
//	//判断是什么原因结束的
//	if (ferror(fp))
//		puts("I/O error when reading");
//	else if (feof(fp))
//		puts("End of file reached successfully");
//	fclose(fp);
//}
//enum { SIZE = 5 };
//int main(void)
//{
//	double a[SIZE] = { 1.,2.,3.,4.,5. };
//	FILE* fp = fopen("test.bin", "wb"); // 必须⽤⼆进制模式
//	fwrite(a, sizeof * a, SIZE, fp); // 写 double 的数组
//	fclose(fp);
//	double b[SIZE];
//	fp = fopen("test.bin", "rb");
//	size_t ret_code = fread(b, sizeof * b, SIZE, fp); // 读 double 的数组
//	if (ret_code == SIZE) {
//		puts("Array read successfully, contents: ");
//		for (int n = 0; n < SIZE; ++n)
//			printf("%f ", b[n]);
//		putchar('\n');
//	}
//	else { // error handling
//		if (feof(fp))
//			printf("Error reading test.bin: unexpected end of file\n");
//		else if (ferror(fp)) {
//			perror("Error reading test.bin");
//		}
//	}
//	fclose(fp);
//}
#include <windows.h>
//VS2022 WIN11环境测试
int main()
{
	FILE* pf = fopen("test.txt", "w");
	fputs("abcdef", pf);//先将代码放在输出缓冲区
	printf("睡眠10秒-已经写数据了，打开test.txt⽂件，发现⽂件没有内容\n");
	Sleep(10000);
	printf("刷新缓冲区\n");
	fflush(pf);//刷新缓冲区时，才将输出缓冲区的数据写到⽂件（磁盘）
	//注：fflush 在⾼版本的VS上不能使⽤了
	printf("再睡眠10秒-此时，再次打开test.txt⽂件，⽂件有内容了\n");
	Sleep(10000);
	fclose(pf);
	//注：fclose在关闭⽂件的时候，也会刷新缓冲区
	pf = NULL;
	return 0;
	/*
		因为有缓冲区的存在，C语⾔在操作⽂件的时候，需要做刷新缓冲区或者在⽂件操作结束的时候关闭⽂件。
		如果不做，可能导致读写⽂件的问题。
	*/
}